﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Segmentation.Business;

namespace Segmentation.UI.Forms
{
    public partial class MainForm : Form
    {
		#region Constructors 

        public MainForm()
        {
            InitializeComponent();
            CloseAll();
            this.toolsToolStripMenuItem.Visible = false;
        }

		#endregion Constructors 

		#region Properties 

        private PictureBoxPage SelectedTab
        {
            get
            {
                if (_tabControl.TabCount > 0)
                {
                    return _tabControl.SelectedTab as PictureBoxPage;
                }
                else
                {
                    return null;
                }
            }
        }

		#endregion Properties 

		#region Methods 

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About();
        }

        private void addGaussianNoiseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddGaussianNoise();
        }

        private void batchToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Batch();
        }

        private void closeAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseAll();
        }

        private void closeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseImage();
        }

        private void createToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CreateModelImage();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Exit();
        }

        private void fileToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            saveImageToolStripMenuItem.Enabled = (_tabControl.TabCount > 0);
            closeToolStripMenuItem.Enabled = (_tabControl.TabCount > 0);
            closeAllToolStripMenuItem.Enabled = (_tabControl.TabCount > 0);
        }

        private void modifiedJSEGIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessJSEG(JSEGAccessor.Mode.JModification1);
        }


        private void modifiedJSEGIIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessJSEG(JSEGAccessor.Mode.JModification2);
        }

        private void modifiedJSEGIIIToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessJSEG(JSEGAccessor.Mode.JModification3);
        }

        private void noiseToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            addGaussianNoiseToolStripMenuItem.Enabled = (this.SelectedTab != null) && this.SelectedTab.IsImageExploited;            
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenImage();
        }

        private void originalJSEGToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ProcessJSEG(JSEGAccessor.Mode.Original);
        }

        private void saveImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveAsImage(this.SelectedTab.Bitmap);
        }

        private void segmentationToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
        {
            originalJSEGToolStripMenuItem.Enabled = (this.SelectedTab != null) && this.SelectedTab.IsImageExploited;
            modifiedJSEGIToolStripMenuItem.Enabled = (this.SelectedTab != null) && this.SelectedTab.IsImageExploited;
            modifiedJSEGIIToolStripMenuItem.Enabled = (this.SelectedTab != null) && this.SelectedTab.IsImageExploited;
            modifiedJSEGIIIToolStripMenuItem.Enabled = (this.SelectedTab != null) && this.SelectedTab.IsImageExploited;
        }

        private void About()
        {
            AboutForm aboutForm = new AboutForm();
            aboutForm.ShowDialog();
        }

        private void AddGaussianNoise()
        {
            if (!this.SelectedTab.IsImageExploited)
            {
                return;
            }
            NoiseOptionsForm wnd = new NoiseOptionsForm();
            if (wnd.ShowDialog() == DialogResult.OK)
            {
                PleaseWaitForm waitForm = new PleaseWaitForm("Please wait until noise generation will be complited.");
                this.SelectedTab.ImageContainer.BeginAddNoise(wnd.PSNR, waitForm.GetCallbackMethod());
                waitForm.ShowDialog();
                this.SelectedTab.Refresh();
                _tsslPSNR.Text = string.Format("PSNR {0}", this.SelectedTab.ImageContainer.PSNR);
            }
        }

        private void Batch()
        {
            throw new NotImplementedException();
        }

        private void CloseAll()
        {
            foreach (TabPage page in _tabControl.TabPages)
            {
                page.Dispose();
            }
            _tabControl.TabPages.Clear();

            _tsslPSNR.Text = string.Empty;
            _tsslNoiseproofFeature.Text = string.Empty;
            _tsslQuality.Text = string.Empty;
            _tsslEffectiveness.Text = string.Empty;
        }

        private void CloseImage()
        {
            if (this.SelectedTab != null)
            {
                this.SelectedTab.Dispose();
            }
        }

        private void CreateModelImage()
        {
            ModelImageForm wnd = new ModelImageForm();
            if (wnd.ShowDialog() == DialogResult.OK)
            {
                CloseAll();
                int width = wnd.ModelWidth;
                int height = wnd.ModelHeight;
                Color color1 = wnd.Color1;
                Color color2 = wnd.Color2;
                _tabControl.Controls.Add(new PictureBoxPage("Model Image", ModelImage.Create(width, height, color1, color2)));
            }
            wnd.Dispose();
        }

        private void Exit()
        {
            this.Close();
        }

        private void OpenImage()
        {
            OpenFileDialog wnd = new OpenFileDialog();
            wnd.Title = "Open Image";
            wnd.FilterIndex = 0;
            wnd.Filter = "Image Files(*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG|All files (*.*)|*.*";

            if (wnd.ShowDialog() == DialogResult.OK)
            {
                CloseAll();
                string fileName = wnd.FileName;
                try
                {
                    Bitmap bitmap = (Bitmap)Bitmap.FromFile(fileName);
                    ImageContainer imageContainer = new ImageContainer(bitmap);
                    _tabControl.Controls.Add(new PictureBoxPage(System.IO.Path.GetFileName(fileName), imageContainer));
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex);
                    MessageBox.Show(string.Format("Cannot open image: {0}", fileName), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            wnd.Dispose();
        }

        private void ProcessJSEG(JSEGAccessor.Mode mode)
        {
            if(!this.SelectedTab.IsImageExploited)
            {
                return;
            }
            JSEGOptionsForm wnd = new JSEGOptionsForm();
            if (wnd.ShowDialog() == DialogResult.OK)
            {
                PleaseWaitForm waitForm = new PleaseWaitForm("Please wait until segmantation will be complited.");
                this.SelectedTab.ImageContainer.BeginSegment(mode, waitForm.GetCallbackMethod());
                waitForm.ShowDialog();

                _tabControl.Controls.Add(new PictureBoxPage("Region map", 
                    BitmapCreater.GetBitmapFromMap(this.SelectedTab.ImageContainer.JSEGAccessor.RegionMap)));
                               
                _tabControl.Controls.Add(new PictureBoxPage("Region map with boundaries", 
                    BitmapCreater.GetBitmapWithBounderies(this.SelectedTab.ImageContainer.JSEGAccessor.RegionMap, 
                        this.SelectedTab.ImageContainer.Bitmap, 
                        0.5)));

                _tabControl.Controls.Add(new PictureBoxPage("Color map", 
                    BitmapCreater.GetBitmapFromMap(this.SelectedTab.ImageContainer.JSEGAccessor.ColorMap)));
                /*
                _tabControl.Controls.Add(new PictureBoxPage("Color map with bounderies", 
                    BitmapCreater.GetBitmapWithBounderies(this.SelectedTab.ImageContainer.JSEGAccessor.ColorMap, 
                        this.SelectedTab.ImageContainer.Bitmap, 
                        0.5)));
                */
                foreach (JImage jImage in this.SelectedTab.ImageContainer.JSEGAccessor.JImages)
                {
                    _tabControl.Controls.Add(new PictureBoxPage("J-image " + jImage.ToString(), 
                        BitmapCreater.GetBitmapFromJ(jImage.JData)));
                }

                if (this.SelectedTab.ImageContainer is ModelImage)
                {
                    ModelImage modelImage = ((ModelImage)this.SelectedTab.ImageContainer);
                    modelImage.CalculateCriterions();
                    _tsslNoiseproofFeature.Text = modelImage.Criterions[0].ToString();
                    _tsslQuality.Text = modelImage.Criterions[1].ToString();
                    _tsslEffectiveness.Text = modelImage.Criterions[2].ToString();
                }
            }
        }

        private void SaveAsImage(Bitmap bitmap)
        {
            SaveFileDialog wnd = new SaveFileDialog();
            wnd.Title = "Save Image";
            wnd.FilterIndex = 0;
            wnd.Filter = "BMP files|*.bmp|JPEG files|*.jpg|GIF files|*.gif|PNG files|*.png|All files|*.*";

            if (wnd.ShowDialog() == DialogResult.OK)
            {
                string filePath = wnd.FileName;
                string ext = System.IO.Path.GetExtension(filePath);
                ImageFormat imageFormat;
                switch (ext.ToUpper())
                {
                    case "BMP":
                        imageFormat = ImageFormat.Bmp;
                        break;
                    case "JPG":
                        imageFormat = ImageFormat.Jpeg;
                        break;
                    case "GIF":
                        imageFormat = ImageFormat.Gif;
                        break;
                    case "PNG":
                        imageFormat = ImageFormat.Png;
                        break;
                    default:
                        imageFormat = ImageFormat.Bmp;
                        break;
                }
                bitmap.Save(filePath, imageFormat);
            }

            wnd.Dispose();
        }

		#endregion Methods
    }
}
